package com.zeyun.EasyOnlineShareCloud.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zeyun.EasyOnlineShareCloud.common.convention.exception.ClientException;
import com.zeyun.EasyOnlineShareCloud.common.convention.exception.ServiceException;
import com.zeyun.EasyOnlineShareCloud.dao.entity.UserDO;
import com.zeyun.EasyOnlineShareCloud.dao.mapper.UserMapper;
import com.zeyun.EasyOnlineShareCloud.dto.req.LoginReqDTO;
import com.zeyun.EasyOnlineShareCloud.dto.req.RegisterReqDTO;
import com.zeyun.EasyOnlineShareCloud.dto.resp.LoginRespDTO;
import com.zeyun.EasyOnlineShareCloud.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Objects;


@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements UserService {

	@Override
	public LoginRespDTO login(LoginReqDTO requestParam) {
		if (!StringUtils.hasText(requestParam.getUsername()) || !StringUtils.hasText(requestParam.getPassword())) {
			throw new ClientException("用户名或密码不能为空");
		}

		// 查询用户
		LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(UserDO::getUsername, requestParam.getUsername())
				.eq(UserDO::getRole, requestParam.getRole())
				.eq(UserDO::getDelFlag, 0);
		UserDO user = baseMapper.selectOne(queryWrapper);

		// 验证用户是否存在
		if (user == null) {
			throw new ClientException("用户不存在");
		}

		// 验证密码
		if (!Objects.equals(requestParam.getPassword(), user.getPassword())) {
			throw new ClientException("密码错误");
		}

		// 验证状态
		if (!"active".equals(user.getStatus())) {
			throw new ClientException("账号已被锁定，请联系管理员");
		}

		// 使用sa-token登录
		StpUtil.login(user.getId(), new SaLoginParameter()
				.setExtra("role", user.getRole())
				.setExtra("username", user.getUsername()));
		// 拿到token
		String tokenValue = StpUtil.getTokenValue();
		// log.info("token信息:{}", StpUtil.getTokenInfo());
		log.info("用户登录成功: {}", user.getUsername());

		// 返回响应对象
		return LoginRespDTO.builder()
				.username(user.getUsername())
				.role(user.getRole())
				.token(tokenValue)
				.build();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void register(RegisterReqDTO requestParam) {
		// 参数校验
		if (!StringUtils.hasText(requestParam.getUsername()) ||
				!StringUtils.hasText(requestParam.getPassword()) ||
				!StringUtils.hasText(requestParam.getEmail())) {
			throw new ClientException("注册信息不完整");
		}

		// 验证用户名是否已存在
		LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(UserDO::getUsername, requestParam.getUsername())
				.or()
				.eq(UserDO::getEmail, requestParam.getEmail());
		UserDO existUser = baseMapper.selectOne(queryWrapper);

		if (existUser != null) {
			if (Objects.equals(existUser.getUsername(), requestParam.getUsername())) {
				throw new ClientException("用户名已存在");
			} else {
				throw new ClientException("邮箱已被注册");
			}
		}

		// 创建用户
		UserDO user = UserDO.builder()
				.username(requestParam.getUsername())
				.password(requestParam.getPassword())
				.email(requestParam.getEmail())
				// 默认用户
				.role("user")
				// 默认状态
				.status("active")
				.build();

		try {
			// 保存到数据库
			boolean saved = save(user);
			if (!saved) {
				throw new ServiceException("用户注册失败，请稍后再试");
			}
			log.info("新用户注册成功: {}", user.getUsername());
		} catch (Exception e) {
			log.error("用户注册失败", e);
			throw new ServiceException("用户注册失败: " + e.getMessage());
		}
	}

	/**
	 * 注销登录
	 */
	@Override
	public void logout() {
		String userId = StpUtil.getLoginId().toString();
		// 登出SA-Token
		StpUtil.logout(userId);
		log.info("用户已登出: {}", userId);
	}
}
